home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / games / larn12s.arc / LARN.ARC / IO.C < prev    next >
C/C++ Source or Header  |  1987-10-28  |  25KB  |  1,028 lines

  1. /* io.c             Larn is copyrighted 1986 by Noah Morgan.
  2.  *
  3.  *    Below are the functions in this file:
  4.  *
  5.  *    setupvt100()     Subroutine to set up terminal in correct mode for game
  6.  *    clearvt100()      Subroutine to clean up terminal when the game is over
  7.  *    getchar()         Routine to read in one character from the terminal
  8.  *    scbr()            Function to set cbreak -echo for the terminal
  9.  *    sncbr()            Function to set -cbreak echo for the terminal
  10.  *    newgame()         Subroutine to save the initial time and seed rnd()
  11.  *
  12.  *    FILE OUTPUT ROUTINES
  13.  *
  14.  *    lprintf(format,args . . .)    printf to the output buffer
  15.  *    lprint(integer)            send binary integer to output buffer
  16.  *    lwrite(buf,len)            write a buffer to the output buffer
  17.  *    lprcat(str)            sent string to output buffer
  18.  *
  19.  *    FILE OUTPUT MACROS (in header.h)
  20.  *
  21.  *    lprc(character)            put the character into the output buffer
  22.  *
  23.  *    FILE INPUT ROUTINES
  24.  *
  25.  *    long lgetc()            read one character from input buffer
  26.  *    long lrint()            read one integer from input buffer
  27.  *    lrfill(address,number)        put input bytes into a buffer
  28.  *    char *lgetw()            get a whitespace ended word from input
  29.  *    char *lgetl()            get a \n or EOF ended line from input
  30.  *
  31.  *    FILE OPEN / CLOSE ROUTINES
  32.  *
  33.  *    lcreat(filename)        create a new file for write
  34.  *    lopen(filename)            open a file for read
  35.  *    lappend(filename)        open for append to an existing file
  36.  *    lrclose()            close the input file
  37.  *    lwclose()            close output file
  38.  *    lflush()            flush the output buffer
  39.  *
  40.  *    Other Routines
  41.  *
  42.  *    cursor(x,y)        position cursor at [x,y]
  43.  *    cursors()        position cursor at [1,24] (saves memory)
  44.  *  cl_line(x,y)             Clear line at [1,y] and leave cursor at [x,y]
  45.  *  cl_up(x,y)            Clear screen from [x,1] to current line.
  46.  *  cl_dn(x,y)             Clear screen from [1,y] to end of display. 
  47.  *  standout(str)         Print the string in standout mode.
  48.  *  set_score_output()         Called when output should be literally printed.
  49.  ** putchar(ch)            Print one character in decoded output buffer.
  50.  ** flush_buf()            Flush buffer with decoded output.
  51.  ** init_term()            Terminal initialization -- setup termcap info
  52.  **    char *tmcapcnv(sd,ss)      Routine to convert VT100 \33's to termcap format
  53.  *    beep()        Routine to emit a beep if enabled (see no-beep in .larnopts)
  54.  *
  55.  * Note: ** entries are available only in termcap mode.
  56.  */
  57.  
  58. #include "header.h"
  59.  
  60. #ifdef SYSV    /* system III or system V */
  61. # ifdef UNIX
  62. #   include <termio.h>
  63. # endif
  64. #define sgttyb termio
  65. #define stty(_a,_b) ioctl(_a,TCSETA,_b)
  66. #define gtty(_a,_b) ioctl(_a,TCGETA,_b)
  67. static int rawflg = 0;
  68. static char saveeof,saveeol;
  69. #define doraw(_a) if(!rawflg){++rawflg;saveeof=_a.c_cc[VMIN];saveeol=_a.c_cc[VTIME];}\
  70.     _a.c_cc[VMIN]=1;_a.c_cc[VTIME]=1;_a.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL)
  71. #define unraw(_a) _a.c_cc[VMIN]=saveeof;_a.c_cc[VTIME]=saveeol;_a.c_lflag |= ICANON|ECHO|ECHOE|ECHOK|ECHONL
  72.  
  73. #else not SYSV
  74.  
  75. #ifndef BSD
  76. #define CBREAK RAW        /* V7 has no CBREAK */
  77. #endif
  78.  
  79. #define doraw(_a) (_a.sg_flags |= CBREAK,_a.sg_flags &= ~ECHO)
  80. #define unraw(_a) (_a.sg_flags &= ~CBREAK,_a.sg_flags |= ECHO)
  81. #include <sgtty.h>
  82. #endif not SYSV
  83.  
  84. #ifndef NOVARARGS    /* if we have varargs */
  85. #include <varargs.h>
  86. #else NOVARARGS    /* if we don't have varargs */
  87. typedef char *va_list;
  88. #define va_dcl int va_alist;
  89. #define va_start(plist) plist = (char *) &va_alist
  90. #define va_end(plist)
  91. #define va_arg(plist,mode) ((mode *)(plist += sizeof(mode)))[-1]
  92. #endif NOVARARGS
  93.  
  94. #define LINBUFSIZE 128        /* size of the lgetw() and lgetl() buffer        */
  95. int lfd;            /*  output file numbers        */
  96. int fd;                /*  input file numbers        */
  97. # ifdef UNIX
  98. static struct sgttyb ttx;    /* storage for the tty modes                    */
  99. # endif
  100. static int ipoint=MAXIBUF,iepoint=MAXIBUF;    /*  input buffering pointers    */
  101. static char lgetwbuf[LINBUFSIZE];    /* get line (word) buffer                */
  102.  
  103. # ifndef UNIX
  104. # ifdef MSDOS
  105. # include <fcntl.h>        /* For O_BINARY */
  106. # endif
  107. # ifdef GEMDOS
  108. # include <osbind.h>
  109. # include <xbios.h>
  110. # endif
  111. int    (*getchfn)(), getche(), kgetch();
  112. # endif
  113.  
  114. /*
  115.  *    setupvt100()         Subroutine to set up terminal in correct mode for game
  116.  *
  117.  *    Attributes off, clear screen, set scrolling region, set tty mode 
  118.  */
  119. setupvt100()
  120.     {
  121.     lprc(T_INIT);
  122.     clear();  setscroll();  scbr(); /* system("stty cbreak -echo"); */
  123. #ifdef MSDOS
  124. # ifdef DGK
  125.     setraw();
  126.     setcursor();
  127.  
  128.     /* Select normal ASCII and line drawing character sets.
  129.      */
  130.     if (DECRainbow)
  131.         lprcat("\033(B\033)0");
  132. # endif
  133. #endif
  134. #ifdef GEMDOS
  135.     init_keys();
  136. #endif
  137.     }
  138.  
  139. /*
  140.  *    clearvt100()          Subroutine to clean up terminal when the game is over
  141.  *
  142.  *    Attributes off, clear screen, unset scrolling region, restore tty mode 
  143.  */
  144. clearvt100()
  145.     {
  146.     lprc(T_END);
  147.     resetscroll();  clear();  sncbr(); /* system("stty -cbreak echo"); */
  148. #ifdef MSDOS
  149. # ifdef DGK
  150.     unsetraw();
  151.     resetcursor();
  152. # endif
  153. #endif
  154. #ifdef GEMDOS
  155.     Bioskeys();
  156. #endif
  157.     }
  158.  
  159. /*
  160.  *    getchar()         Routine to read in one character from the terminal
  161.  */
  162. getchar()
  163.     {
  164.     char byt;
  165. #ifdef EXTRA
  166.     c[BYTESIN]++;
  167. #endif
  168.     lflush();        /* be sure output buffer is flushed */
  169. # ifndef UNIX
  170.     if ((byt = (*getchfn)()) == '\r')
  171.         byt = '\n';
  172.     return byt;
  173. # else
  174.     read(0,&byt,1);     /* get byte from terminal */
  175.     return(byt);
  176. # endif
  177.     }
  178.  
  179. /*
  180.  *    scbr()        Function to set cbreak -echo for the terminal
  181.  *
  182.  *    like: system("stty cbreak -echo")
  183.  */
  184. scbr()
  185.     {
  186. # ifndef UNIX
  187.     /* Set up to use the direct console input call which may
  188.      * read from the keypad;
  189.      */
  190.     getchfn = kgetch;
  191. # else
  192.     gtty(0,&ttx);        doraw(ttx);        stty(0,&ttx);
  193. # endif
  194.     }
  195.  
  196. /*
  197.  *    sncbr()        Function to set -cbreak echo for the terminal
  198.  *
  199.  *    like: system("stty -cbreak echo")
  200.  */
  201. sncbr()
  202.     {
  203. # ifndef UNIX
  204.     /* Set up to use the direct console input call with echo, getche()
  205.      */
  206.     getchfn = getche;
  207. # else
  208.     gtty(0,&ttx);        unraw(ttx);        stty(0,&ttx);
  209. # endif
  210.     }
  211.  
  212. /*
  213.  *    newgame()         Subroutine to save the initial time and seed rnd()
  214.  */
  215. newgame()
  216.     {
  217.     register long *p,*pe;
  218.     for (p=c,pe=c+100; p<pe; *p++ =0);
  219.     time(&initialtime);        srand(initialtime);
  220.     lcreat((char*)0);    /* open buffering for output to terminal */
  221.     }
  222.  
  223. /*
  224.  *    lprintf(format,args . . .)        printf to the output buffer
  225.  *        char *format;
  226.  *        ??? args . . .
  227.  *
  228.  *    Enter with the format string in "format", as per printf() usage
  229.  *        and any needed arguments following it
  230.  *    Note: lprintf() only supports %s, %c and %d, with width modifier and left
  231.  *        or right justification.
  232.  *    No correct checking for output buffer overflow is done, but flushes 
  233.  *        are done beforehand if needed.
  234.  *    Returns nothing of value.
  235.  */
  236. #ifdef lint
  237. /*VARARGS*/
  238. lprintf(str)
  239.     char *str;
  240.     {
  241.     char *str2;
  242.     str2 = str;
  243.     str = str2; /* to make lint happy */
  244.     }
  245. /*VARARGS*/
  246. sprintf(str)
  247.     char *str;
  248.     {
  249.     char *str2;
  250.     str2 = str;
  251.     str = str2; /* to make lint happy */
  252.     }
  253. #else lint
  254. /*VARARGS*/
  255. lprintf(va_alist)
  256. va_dcl
  257.     {
  258.     va_list ap;    /* pointer for variable argument list */
  259.     register char *fmt;
  260.     register char *outb,*tmpb;
  261.     register long wide,left,cont,n;        /* data for lprintf    */
  262.     char db[12];            /* %d buffer in lprintf    */
  263.  
  264.     va_start(ap);    /* initialize the var args pointer */
  265.     fmt = va_arg(ap, char *);    /* pointer to format string */
  266.     if (lpnt >= lpend) lflush(); 
  267.     outb = lpnt;
  268.     for ( ; ; )
  269.         {
  270.         while (*fmt != '%')
  271.             if (*fmt) *outb++ = *fmt++;  else { lpnt=outb;  return; }
  272.         wide = 0;    left = 1;    cont=1;
  273.         while (cont)
  274.           switch(*(++fmt))
  275.             {
  276.             case 'd':    n = va_arg(ap, long);
  277.                         if (n<0) { n = -n;  *outb++ = '-';  if (wide) --wide; }
  278.                         tmpb = db+11;    *tmpb = (char)(n % 10 + '0');
  279.                         while (n>9)  *(--tmpb) = (char)((n /= 10) % 10 + '0');
  280.                         if (wide==0)  while (tmpb < db+12) *outb++ = *tmpb++;
  281.                         else
  282.                             {
  283.                             wide -= db-tmpb+12;
  284.                             if (left)  while (wide-- > 0) *outb++ = ' ';
  285.                             while (tmpb < db+12) *outb++ = *tmpb++;
  286.                             if (left==0)  while (wide-- > 0) *outb++ = ' ';
  287.                             }
  288.                         cont=0;    break;
  289.  
  290.             case 's':    tmpb = va_arg(ap, char *);
  291.                         if (wide==0)  { while (*outb++ = *tmpb++);  --outb; } 
  292.                         else
  293.                             {
  294.                             n = wide - strlen(tmpb);
  295.                             if (left)  while (n-- >